//shmServer.cpp
#include "comm.hpp"

// 程序加载的时候自动构建全局变量，会调用类的构造函数来创建管道
Init init;
// 程序退出的时候，全局变量会自动调用析构函数，会删除管道文件

int main()
{
    // 1.创建公共的key
    key_t k = ftok(PATH_NAME, PROJ_ID);
    assert(k != -1);
    Log("create key success", Debug) << " server key : " << k << endl;

    // 2.创建共享内存 -- 建议创建一个新的共享内存 -- 通信的发起者
    int shmid = shmget(k, SHM_SIZE, IPC_CREAT | IPC_EXCL | 0666);
    if (shmid == -1)
    {
        perror("shmget");
        exit(1);
    }
    Log("create shm success", Debug) << " shmid : " << shmid << endl;

    // 3.将指定的共享内存，挂接到自己的地址空间
    char* shmaddr = (char*)shmat(shmid, nullptr, 0);
    assert(shmaddr != (void*)-1);
    Log("shm attach success", Debug) << " shmid : " << shmid << endl;

    // 这里就可以通信了
    // 简单来说共享内存就是字符串，有地址，有大小，就像malloc出来的一样

    // 访问控制，通过创建管道文件实现访问控制
    int fd = OpenFIFO(FIFO_NAME, READ);
    while (true)
    {
        Wait(fd);
        printf("client: %s\n", shmaddr);
        if (strcmp(shmaddr, "quit") == 0) break;
    }

    // while (true)
    // {
    //     // 读取
    //     printf("client: %s\n", shmaddr);
    //     if (strcmp(shmaddr, "quit") == 0) break;
    //     sleep(1);
    // }

    // 4.将指定的共享内存，从自己的地址空间去关联
    int n = shmdt(shmaddr);
    assert(n != -1);
    (void)n;
    Log("shm detach success", Debug) << " shmid : " << shmid << endl;

    // 删除共享内存
    n = shmctl(shmid, IPC_RMID, nullptr);
    assert(n != -1);
    (void)n;
    Log("delete shm success", Debug) << " shmid : " << shmid << endl;

    CloseFIFO(fd);

    return 0;
}